package com.jds.clickhouse.web.service.impl.portray;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jds.clickhouse.web.service.portray.QySecretMappingService;
import com.jds.link4sales.common.constant.RedisConstants;
import com.jds.link4sales.common.exception.BusinessException;
import com.jds.link4sales.common.result.ResultJson;
import com.jds.link4sales.model.dto.QySecretMappingDto;
import com.jds.link4sales.model.entity.portray.QySecretMapping;
import com.jds.link4sales.model.mapper.portray.QySecretMappingMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * impl qy秘密映射服务
 * impl qy秘密映射服务
 *
 * @author JACKSON G
 * @date 2020/11/03
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class QySecretMappingServiceImpl extends ServiceImpl<QySecretMappingMapper, QySecretMapping> implements QySecretMappingService {

    @Value("${qywx.url.getToken}")
    private String tokenUrl;

    @Value("${qywx.url.getUserId}")
    private String userIdUrl;

    @Value("${qywx.url.getSignature}")
    private String signatureUrl;

    @Value("${qywx.url.makeTag}")
    private String makeTagUrl;

    @Value("${qywx.url.remark}")
    private String remarkUrl;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private final QySecretMappingMapper qySecretMappingMapper;


    @Override
    public String getQyToken(Integer qyId) {
        String token = redisTemplate.opsForValue().get(String.format(RedisConstants.QY_TOKEN_CACHE_KEY, qyId));
        if (StringUtils.isBlank(token)) {
            try {
                QySecretMapping query = new QySecretMapping();
                query.setQyId(qyId);
                QySecretMapping qySecretMapping = qySecretMappingMapper.selectOne(new QueryWrapper<>(query).last("limit 1"));
                String secret = qySecretMapping.getSecret();
                String clientId = qySecretMapping.getClientId();
                log.info("获取企业微信系统token clientId:{}, secret:{}", clientId, secret);
                String result = HttpUtil.get(String.format(tokenUrl, clientId, secret));
                log.info("获取企业微信系统token, result:{}", result);
                if (StringUtils.isBlank(result)) {
                    return null;
                }
                JSONObject json = JSONObject.parseObject(result);
                if (json.containsKey("access_token")) {
                    token = json.getString("access_token");
                    redisTemplate.opsForValue().set(String.format(RedisConstants.QY_TOKEN_CACHE_KEY, qyId), token, 10L, TimeUnit.DAYS);
                    return token;
                }
            } catch (Exception e1) {
                log.error("解析企业微信返回结果异常", e1);
            }
            return null;
        } else {
            return token;
        }
    }

    @Override
    public String getQyEmpUserId(Integer qyId, String agentId, String corpId, String code) {
        String token = getQyToken(qyId);
        if (StringUtils.isBlank(token)) {
            return null;
        }
//        Map<String, String> headers = new HashMap<>(4);
//        headers.put("Authorization", "Bearer " + token);
        log.info("获取企业微信系统userId corpId:{}, agent:{}, code:{}", corpId, agentId, code);
        String result = HttpRequest.get(String.format(userIdUrl, corpId, agentId, code)).header("Authorization", "Bearer " + token).timeout(20000).execute().body();
        log.info("获取企业微信系统userId result:{}", result);
        if (StringUtils.isBlank(result)) {
            return null;
        }
        try {
            JSONObject json = JSONObject.parseObject(result);
            if (json.containsKey("code") && json.getIntValue("code") == 1) {
                return json.getString("result");
            }
        } catch (Exception e) {
            log.error("解析企业微信返回结果异常", e);
        }
        return null;
    }

    @Override
    @SentinelResource(value = "signature", entryType = EntryType.IN, blockHandler = "getSignatureBlockHander")
    public JSONObject getSignature(Integer qyId, String agentId, String corpId, String url) {
        String token = getQyToken(qyId);
        if (StringUtils.isBlank(token)) {
            return null;
        }
//        Map<String, String> headers = new HashMap<>(4);
//        headers.put("Authorization", "Bearer " + token);
        log.info("获取企业微信系统signature corpId:{}, agentId:{}, url:{}", corpId, agentId, url);
        String result = HttpRequest.get(String.format(signatureUrl, corpId, agentId, url)).header("Authorization", "Bearer " + token).timeout(20000).execute().body();
        log.info("获取企业微信系统signature result:{}", result);
        if (StringUtils.isBlank(result)) {
            return null;
        }
        try {
            JSONObject json = JSONObject.parseObject(result);
            if (json.containsKey("code") && json.getIntValue("code") == 1) {
                return json.getJSONObject("result");
            }
        } catch (Exception e) {
            log.error("解析企业微信返回结果异常", e);
        }
        return null;
    }

    @Override
    public ResultJson<Object> getAll() {
        List<QySecretMapping> qySecretMappings = qySecretMappingMapper.selectList(new LambdaQueryWrapper<QySecretMapping>()
                .select(QySecretMapping::getId,QySecretMapping::getQyName,QySecretMapping::getQyId));
        return ResultJson.success(qySecretMappings);
    }

    public JSONObject getSignatureBlockHander(Integer qyId, String agentId, String corpId, String url, BlockException e) {
        log.error("block by sentinel", e);
        log.error("qyId:{}, agentId:{}, corpId:{}, url:{}", qyId, agentId, corpId, url);
        throw new BusinessException("当前系统繁忙, 请稍候再试");
    }

    @Override
    public int saveQySecretMapping(QySecretMappingDto dto) {
        try {
            QySecretMapping query = new QySecretMapping();
            query.setQyId(dto.getQyId());
            QySecretMapping qySecretMapping = qySecretMappingMapper.selectOne(new QueryWrapper<>(query).last("limit 1"));
            if (qySecretMapping != null) {
                QySecretMapping param = new QySecretMapping();
                param.setSecret(dto.getSecret());
                param.setUpdateTime(new Date());
                param.setClientId(dto.getClientId());
                param.setAgentId(dto.getAgentId());
                param.setQyName(dto.getQyName());
                param.setId(qySecretMapping.getId());
                return qySecretMappingMapper.updateById(param);
            } else {
                QySecretMapping mapping = QySecretMapping.builder()
                        .qyId(dto.getQyId())
                        .secret(dto.getSecret())
                        .clientId(dto.getClientId())
                        .agentId(dto.getAgentId())
                        .createTime(new Date())
                        .updateTime(new Date())
                        .qyName(dto.getQyName())
                        .build();
                return qySecretMappingMapper.insert(mapping);
            }
        } catch (Exception e) {
            log.error("保存企业号映射信息异常", e);
            return 0;
        }
    }
}
